/*
 * (C) 2007-2010 Taobao Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *
 *
 * Version: 0.1: ups_mutator.h,v 0.1 2010/09/16 17:47:29 chuanhui Exp $
 *
 * Authors:
 *   chuanhui <rizhao.ych@taobao.com>
 *     - some work details if you want
 *
 */
#ifndef __OCEANBASE_CHUNKSERVER_UPS_MUTATOR_H__
#define __OCEANBASE_CHUNKSERVER_UPS_MUTATOR_H__

#include "common/ob_mutator.h"

namespace oceanbase
{
  namespace updateserver
  {
    // ObUpsMutator is the internal mutator class used by Update Server.
    // It may be the mutator received from client API, and it can also be FREEZE_MEMTABLE
    // and DROP_MEMTABLE command generated by Update Server Master and then replicated to
    // Update Server Slave.
    class ObUpsMutator
    {
      public:
        ObUpsMutator();
        ObUpsMutator(common::ModuleArena &arena);
        virtual ~ObUpsMutator();

      public:
        // Gets the associated mutator
        common::ObMutator& get_mutator();

      public:
        int set_freeze_memtable();
        int set_drop_memtable();
        int set_first_start();
        int set_check_cur_version();
        int set_check_sstable_checksum();
        bool is_normal_mutator() const;
        bool is_freeze_memtable() const;
        bool is_drop_memtable() const;
        bool is_first_start() const;
        bool is_check_cur_version() const;
        bool is_check_sstable_checksum() const;
        void set_mutate_timestamp(const int64_t timestamp);
        int64_t get_mutate_timestamp() const;
        void set_memtable_checksum_before_mutate(const int64_t checksum);
        int64_t get_memtable_checksum_before_mutate() const;
        void set_memtable_checksum_after_mutate(const int64_t checksum);
        int64_t get_memtable_checksum_after_mutate() const;

        void set_cur_major_version(const uint64_t cur_major_version);
        uint64_t get_cur_major_version() const;
        void set_cur_minor_version(const uint64_t cur_minor_version);
        uint64_t get_cur_minor_version() const;
        void set_last_bypass_checksum(const uint64_t last_bypass_checksum);
        uint64_t get_last_bypass_checksum() const;
        void set_sstable_checksum(const uint64_t sstable_checksum);
        uint64_t get_sstable_checksum() const;
        int32_t get_flag() const;

      public:
        virtual void reset_iter();
        virtual int next_cell();
        virtual int get_cell(common::ObMutatorCellInfo** cell);
        virtual int get_cell(common::ObMutatorCellInfo** cell, bool *is_row_changed);

      public:
        int serialize(char* buf, const int64_t buf_len, int64_t& pos) const;
        int deserialize(const char* buf, const int64_t buf_len, int64_t& pos);
        int64_t get_serialize_size(void) const;
        int serialize_header(char* buf, const int64_t buf_len, int64_t& pos) const;
        int deserialize_header(const char* buf, const int64_t buf_len, int64_t& pos);
        void clear();
        void reset();

      private:
        static const int32_t NORMAL_FLAG = 0;
        static const int32_t FREEZE_FLAG = 1;
        static const int32_t DROP_FLAG = 2;
        static const int32_t START_FLAG = 3;
        static const int32_t CHECK_CUR_VERSION_FLAG = 4;
        static const int32_t CHECK_SSTABLE_CHECKSUM_FLAG = 5;

      private:
        int32_t version_;
        int32_t flag_; // freeze/drop/row_exist flag
        union
        {
          int64_t mutate_timestamp_;
          uint64_t last_bypass_checksum_;
          uint64_t sstable_checksum_;
        };
        union
        {
          int64_t memtable_checksum_before_mutate_;
          uint64_t cur_major_version_;
        };
        union
        {
          int64_t memtable_checksum_after_mutate_;
          uint64_t cur_minor_version_;
        };
        common::ObMutator mutator_;
    };
  }
}

#endif //__UPS_MUTATOR_H__

